//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<CEffect9.h>
///	@path	~/src/graphics/dx9/
///	@date	2007/11/15
///	@desc	Effect implementation in DX 9.

#pragma once

#include "xeres.h"

#include <map>

#include "graphics/IEffect.h"
#include "graphics/IEffectPool.h"
#include "graphics/ITechnique.h"
#include "graphics/IShaderVariable.h"
#include "graphics/ITexture.h"
#include "graphics/dx9/CDevice9.h"

#include <d3dx9.h>

namespace xeres {

	/*!
		\class	CEffect9
		\brief	Effect implementation in DX 9.
	*/
	class CEffect9 : public IEffect
	{
	public:

		/// \ctor
		CEffect9( ID3DXEffect * effect , RefWeak<IEffectPool> pool );

		/// \dtor
		virtual ~CEffect9( void );

		DECL_IOBJECT_CLASS( CEffect9 , IEffect );

	public:

	//@ interface

		/*!
			\brief		Called when device is lost or before reset.
		*/
		virtual bool OnLostDevice( void );

		/*!
			\brief		Called after device is reset.
		*/
		virtual bool OnResetDevice( RefWeak<IDevice> device );

		/*! 
			\brief		Get effect pool.
		*/
		virtual RefWeak<IEffectPool> GetPool( void );

		/*!
			\brief		Get effect variable count.
		*/
		virtual size_t GetVariableCount( void );

		/*!
			\brief		Get effect variable by index.
		*/
		virtual RefPass< IShaderVariable > GetVariableByIndex( size_t index );

		/*!
			\brief		Get effect variable by name.
		*/
		virtual RefPass< IShaderVariable > GetVariableByName( const AString& name );

		/*! 
			\brief		Get effect variable by semantic.
		*/
		virtual RefPass< IShaderVariable > GetVariableBySemantic( const AString& semantic );

		/*!
			\brief		Deregister variable cache.
		*/
		virtual void UnusedVariable( RefWeak< IShaderVariable > var );

		/*!
			\brief		Get technique count.
		*/
		virtual size_t GetTechniqueCount( void );

		/*!
			\brief		Get technique by index.
		*/
		virtual RefPass< ITechnique > GetTechnique( size_t index );

		/*!
			\brief		Get technique by name.
		*/
		virtual RefPass< ITechnique > GetTechnique( const AString& name );

		/*!
			\brief		Deregister technique cache.
		*/
		virtual void UnusedTechnique( RefWeak< ITechnique > tech );

		/*! 
			\brief		Get effect interface.
		*/
		virtual IUnknown * GetEffectInterface( void );


	//@ local

		/*!
			\brief		Get DirectX Effect interface.
		*/
		ID3DXEffect * GetEffect( void ) const { return m_pEffect; }

		/*!
			\brief		Get effect DX 9 interface.
		*/
		ID3DXEffect * operator -> ( void ) const { return m_pEffect; }

	private:

		// get variable
		RefPass<IShaderVariable> GetVariable( D3DXHANDLE handle );

		// get technique
		RefPass<ITechnique> GetTechnique( D3DXHANDLE handle );

	//@ data

		// effect interface
		ID3DXEffect *		m_pEffect;

		// effect pool
		Ref<IEffectPool>	m_pool;

		// effect description
		D3DXEFFECT_DESC		m_desc;

		// techniques
		std::map< D3DXHANDLE , RefWeak<ITechnique> >		m_techniques;

		// map
		std::map< D3DXHANDLE , RefWeak<IShaderVariable> >	m_parameters;
	};

} // namespace xeres
